home *** CD-ROM | disk | FTP | other *** search
-
- /**************************************************************************/
- /* Mem.c */
- /*Contains code for reading an entire sample into memory at once */
- /*This is used when it isn't practical to read the sound sample from */
- /*disk as it is played (e.g. when the sample is on a floppy). */
- /*Data is read in in blocks that are the same size as the buffer size */
- /*(optionally) specified by the user using the -b flag, thereby not */
- /*requiring the user to have a block of contiguous memory as large as */
- /*the sample. */
- /*The memory blocks are stored as a linked list; there are two linked */
- /*lists, one for each channel of a stereo sample (the list for the left */
- /*channel is used if a mono sample is being played) */
- /**************************************************************************/
-
- #include <exec/types.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
-
- #include "dsound.h"
-
- extern BOOL loop;
-
- typedef struct memBlock
- {
- struct memBlock *next; /*The next memory block in the list*/
- ULONG blockLength; /*The size of this memory block*/
- } memBlock;
-
- /*The linked-list head pointers for each channel*/
- memBlock *left=NULL;
- memBlock *right=NULL;
-
- memBlock *leftHeader=NULL;
- memBlock *rightHeader=NULL;
-
- /*Read the sample (pointed to by file) into memory*/
- void storeLeft(BPTR file,ULONG length,ULONG blockLength)
- {
- memBlock *temp;
- memBlock *lastLeft;
-
- /*Loop while there's data to be stored...*/
- while(length!=0)
- {
- /*Get the amount of data to be read next (max of blockLength bytes)*/
- blockLength=MIN(blockLength,length);
-
- /*Allocate the memory*/
- temp=(memBlock *)AllocMem(blockLength+8,0L);
-
- /*Exit if there was a problem*/
- if(temp==NULL)
- {
- WriteMsg("Couldn't allocate needed memory\n");
- cleanup(500);
- }
-
- /*Get the length of the data block*/
- temp->blockLength=blockLength;
- temp->next=NULL;
-
- if(left==NULL)
- leftHeader=left=lastLeft=temp; /*First block of data...*/
- else
- { /* Add another block to the end of the list*/
- lastLeft->next=temp;
- lastLeft=temp;
- }
-
- /*Actually read the data, now that the allocated memory block*/
- /*is in place*/
- Read(file,lastLeft+1,blockLength);
-
- /*Subtract the amount read from the total yet to read*/
- length-=blockLength;
- }
-
- return;
- }
-
- /*Delete any remaining memory blocks associated with the left channel*/
- void deleteLeft(void)
- {
- memBlock *temp,*next;
-
- if(leftHeader==NULL)
- next=left;
- else
- next=leftHeader;
-
- /*Loop until we run out of memory blocks*/
- while(next!=NULL)
- {
- /*Get the next block*/
- temp=next;
- next=temp->next;
-
- /*Free the current block*/
- FreeMem(temp,temp->blockLength+8);
- }
-
- return;
- }
-
- /*Get the next available block of sample data associated with the */
- /*left channel*/
- void getLeft(APTR dest)
- {
- memBlock *temp;
-
- /*If there is no dest left, do nothing*/
- if(dest==NULL)
- return;
-
- /*If there is no data left, try to start over from the beginning*/
- if(left==NULL)
- {
- if(leftHeader==NULL)
- return;
- left=leftHeader;
- }
-
- /*Copy the sample data from the memory block to the destination buffer*/
- CopyMem(left+1,dest,left->blockLength);
-
- /*Set the next block as the head of the list*/
- temp=left;
- left=left->next;
-
- /*Free the memory whose contents we just copied, if we're not looping*/
- if(loop==FALSE)
- {
- FreeMem(temp,temp->blockLength+8);
- leftHeader=NULL;
- }
-
- return;
- }
-
- /*Read the sample (pointed to by file) into memory*/
- void storeRight(BPTR file,ULONG length,ULONG blockLength)
- {
- memBlock *temp;
- memBlock *lastRight;
-
- /*Loop while there's data to be stored...*/
- while(length!=0)
- {
- /*Get the amount of data to be read next (max of blockLength bytes)*/
- blockLength=MIN(blockLength,length);
-
- /*Allocate the memory*/
- temp=(memBlock *)AllocMem(blockLength+8,0L);
-
- /*Exit if there was a problem*/
- if(temp==NULL)
- {
- WriteMsg("Couldn't allocate needed memory\n");
- cleanup(500);
- }
-
- /*Get the length of the data block*/
- temp->blockLength=blockLength;
- temp->next=NULL;
-
- if(right==NULL)
- rightHeader=right=lastRight=temp; /*First block of data...*/
- else
- { /* Add another block to the end of the list*/
- lastRight->next=temp;
- lastRight=temp;
- }
-
- /*Actually read the data, now that the allocated memory block*/
- /*is in place*/
- Read(file,lastRight+1,blockLength);
-
- /*Subtract the amount read from the total yet to read*/
- length-=blockLength;
- }
-
- return;
- }
-
- /*Delete any remaining memory blocks associated with the right channel*/
- void deleteRight(void)
- {
- memBlock *temp,*next;
-
- if(rightHeader==NULL)
- next=right;
- else
- next=rightHeader;
-
- /*Loop until we run out of memory blocks*/
- while(next!=NULL)
- {
- /*Get the next block*/
- temp=next;
- next=temp->next;
-
- /*Free the current block*/
- FreeMem(temp,temp->blockLength+8);
- }
-
- return;
- }
-
- /*Get the next available block of sample data associated with the */
- /*right channel*/
- void getRight(APTR dest)
- {
- memBlock *temp;
-
- /*If there is no dest, do nothing*/
- if(dest==NULL)
- return;
-
- /*If there is no data right, try to start over from the beginning*/
- if(right==NULL)
- {
- if(rightHeader==NULL)
- return;
- right=rightHeader;
- }
-
- /*Copy the sample data from the memory block to the destination buffer*/
- CopyMem(right+1,dest,right->blockLength);
-
- /*Set the next block as the head of the list*/
- temp=right;
- right=right->next;
-
- /*Free the memory whose contents we just copied, if we're not looping*/
- if(loop==FALSE)
- {
- FreeMem(temp,temp->blockLength+8);
- rightHeader=NULL;
- }
-
- return;
- }
-
-